
package it.intecs.pisa.smarcos.base;

import it.intecs.pisa.smarcos.R;
import it.intecs.pisa.smarcos.R.string;

import java.util.Locale;

import android.content.Context;
import android.content.Intent;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;


public class SpeechManager implements OnInitListener {
	private static SpeechManager instance;
	private static final String TAG = SpeechManager.class.getSimpleName();

	Context context;

	private boolean speechInitialized=false;
	private TextToSpeech tts=null;
	private String language; 
	
	public static SpeechManager getInstance(Context con)
	{
		Log.d(TAG, "getInstance");

		if(instance==null)
			instance=new SpeechManager(con);

		return instance;
	}
	
	public static void nullInstance(){
		instance = null;
	}
	
	private SpeechManager(Context con) {

		this.context = con;       	
		tts = new TextToSpeech(con, this);
	}


	public void onInit(int status) {
		if (status == TextToSpeech.SUCCESS) {

			ttsInit();
			Intent intent;
			intent=new Intent("TTS READY");
			intent.addCategory(Intent.CATEGORY_DEFAULT);		
			context.sendBroadcast(intent);
		} else
			Log.d(TAG, "TTS Init Error");
	}
	
	public void ttsInit(){

		speechInitialized = true;

		// Align TTS language to the device language 
		if (Locale.getDefault().getLanguage() != tts.getLanguage().getLanguage()){
			int result = tts.setLanguage(Locale.getDefault());
			if (result == TextToSpeech.LANG_MISSING_DATA ||
					result == TextToSpeech.LANG_NOT_SUPPORTED) {
				// Lanuage data is missing or the language is not supported.
				Log.e(TAG, "Language is not available.");
			}
		}
		language = (tts.getLanguage()).getLanguage();
		Log.d(TAG, "TTS language " + language);

	}	

	
	public String getLanguage(){
		return language;
	}
	
	public void say(int num) {
		switch (num) {
		case 1:
			say(context.getString(R.string.TTS_Go_right), true, false);
			break;

		case  2: 
			say(context.getString(R.string.TTS_Go_down), true, false);
			break;

		case  3: 
			say(context.getString(R.string.TTS_Go_up), true, false);
			break;

		case  4: 
			say(context.getString(R.string.TTS_Go_left), true, false);
			break; 

		case  5: 
			say(context.getString(R.string.TTS_Go_right_and_up), true, false);
			break;

		case  6: 
			say(context.getString(R.string.TTS_Go_left_and_up), true, false);
			break;

		case  7: 
			say(context.getString(R.string.TTS_Go_right_and_down), true, false);
			break; 

		case  8: 
			say(context.getString(R.string.TTS_Go_left_and_down), true, false);
			break;
			
		default:
			say(context.getString(num), true, false);
			break;
		}
	}	
	
	public void sayPattern(String s, boolean waitEnd, boolean sayFast) {
		if (s.matches("\\s|\\W"))
			saySpecialChar(s, waitEnd, sayFast);
		else					
			say(s, waitEnd, sayFast);
	}
	
	public void saySpecialChar(String mark, boolean waitEnd, boolean sayFast) {

		if (mark.equals(" ")){
			say(context.getString(R.string.K_Space), waitEnd, sayFast);
			return;
		}	
		if (mark.equals(".")){
			say(context.getString(R.string.SC_16), waitEnd, sayFast);
			return;
		}	
		if (mark.equals(",")){ 
			say(context.getString(R.string.SC_17), waitEnd, sayFast);
			return;
		}	
		if (mark.equals("?")){ 
			say(context.getString(R.string.SC_19), waitEnd, sayFast);
			return;
		}	
		if (mark.equals("@"))
			say(context.getString(R.string.SC_1), waitEnd, sayFast);
		if (mark.equals("#")) 
			say(context.getString(R.string.SC_2), waitEnd, sayFast);
		if (mark.equals("$"))
			say(context.getString(R.string.SC_3), waitEnd, sayFast);
		if (mark.equals("%"))
			say(context.getString(R.string.SC_4), waitEnd, sayFast);
		if (mark.equals("&")) 
			say(context.getString(R.string.SC_5), waitEnd, sayFast);
		if (mark.equals("*")) 
			say(context.getString(R.string.SC_6), waitEnd, sayFast);
		if (mark.equals("-"))
			say(context.getString(R.string.SC_7), waitEnd, sayFast);
		if (mark.equals("=")) 
			say(context.getString(R.string.SC_8), waitEnd, sayFast);
		if (mark.equals("("))
			say(context.getString(R.string.SC_9), waitEnd, sayFast);
		if (mark.equals(")"))
			say(context.getString(R.string.SC_10), waitEnd, sayFast);
		if (mark.equals("!")) 
			say(context.getString(R.string.SC_11), waitEnd, sayFast);
		if (mark.equals("\"")) 
			say(context.getString(R.string.SC_12), waitEnd, sayFast);
		if (mark.equals("\'"))
			say(context.getString(R.string.SC_13), waitEnd, sayFast);
		if (mark.equals(":")) 
			say(context.getString(R.string.SC_14), waitEnd, sayFast);
		if (mark.equals(";"))
			say(context.getString(R.string.SC_15), waitEnd, sayFast);
		if (mark.equals("/")) 
			say(context.getString(R.string.SC_18), waitEnd, sayFast);
		if (mark.equals("_")) 
			say(context.getString(R.string.SC_20), waitEnd, sayFast);
	}	
	
	/**
	 * 
	 * @param str The string to say
	 * @param waitEnd It specifies if wait until the string has been completely spoken before return 
	 * @param sayFast It specifies if the string must be spoken slow or fast
	 */
	public void say(String str, boolean waitEnd, boolean sayFast){
		
		if (speechInitialized == true){

			if (sayFast == true)
				tts.setPitch((float) 1.2);
			else
				tts.setPitch((float) 1);


			tts.speak(str, TextToSpeech.QUEUE_FLUSH, null);
				
			if (waitEnd == true)
				while (tts.isSpeaking()){
				}			
			
		}else
			Log.d(TAG, "TTS not initialized");
	}
		
		
		
	public void shutUp(){
		if (tts != null) {
			tts.stop();
		}
	}
	
	public void close(){
		if (tts != null) {
			tts.stop();
			tts.shutdown();
		}
	}	
}
